<?php
/**
 * Created by PhpStorm.
 * User: tandunzhao
 * Date: 2018/5/30
 * Time: 下午1:51
 */

namespace App\Http\Controllers\Api\Shop;

use App\Http\Controllers\Controller;

use App\Modules\Order\Services\OrderService;
use App\Modules\Shop\Services\CartService;
use App\Modules\Shop\Services\CouponService;
use App\Modules\Shop\Services\GiftSendService;
use App\Modules\Shop\Services\OrderProductsService;
use App\Modules\Shop\Services\ProductsSpecifictionService;
use Illuminate\Http\Request;

class OrderController extends Controller
{
    /**
     * 订单详情
     * @param Request $request
     * @return mixed
     */
    public function orderDetail(Request $request) {
        $order_product_id = $request->input('order_product_id','');
        $type = $request->input('type','');

        if(empty($order_product_id) || empty($type)) {
            return response()->error('PARAM_EMPTY');
        }
        if($type == 2) {
            $order_info = OrderProductsService::getByid($order_product_id);
            $order_info->order->address;
            $order_info->product->img_thum = env('APP_DOMAIN').$order_info->product->img_thum;
            $order_info->product_specific;
            $order_info->status = OrderProductsService::ORDER_STATUS_NUM_TO_STR_HASH[$order_info->status];
        }else{
            $order_info = OrderService::findById($order_product_id);
            $order_info->order_products;
            $order_info->address;
            foreach ($order_info->order_products as $order_product){
                $order_product->product_specific;
                $order_product->product->img_thum = env('APP_DOMAIN').$order_product->product->img_thum;
            }
            $order_info->price = $order_info->order_products->sum('price');
            $order_info->discount = $order_info->order_products->sum('discount');
            $order_info->amount = $order_info->order_products->sum('amount');
            $order_info->status =OrderProductsService::ORDER_STATUS_NUM_TO_STR_HASH[$order_info->status];

        }
        $order_info->now_time=date('Y-m-d H:i:s');
        return response()->success($order_info);
    }

    /**
     * 统一下单
     * input eg. {
     *              'goods_list':[{"goods_id":"11","goods_specific_id":"2","count":"2","is_vip_product":1,"is_gift":0,"phone":"133333333"},
     *                          {"goods_id":"12","goods_specific_id":"5","count":"3","is_vip_product":1,"is_gift":0,"phone":"133333333"}],
     *             'discount_coupon_id':1,
     *             'addr_id:':1,
     *             'payment_source':'ALIPAY'
     *             'remark':''
     *           }
     * @param Request $request
     * @return mixed
     */
    public function generate_order(Request $request) {
        $uid = $this->getLoginUserId();
        $inputs = $request->json();
        $input_arr = $inputs->all();
        if(!$input_arr) {
            return response()->error('PARAM_EMPTY');
        }
        if(!$this->validate_order_input_param($input_arr)) {
            return response()->error('PARAM_ERROR');
        }
        if(!in_array($input_arr['payment_source'],['ALIPAY','WECHAT'])) {
            return response()->error('PARAM_ERROR');
        }

        $sum_price = 0;
        $goods_spec_id_list = array_column($input_arr['goods_list'],'goods_specific_id');
        $goods_spec_list = ProductsSpecifictionService::getProductSpecByIds($goods_spec_id_list);
        \DB::beginTransaction();
        try{
            foreach ($input_arr['goods_list'] as $key=>$value) {
                foreach ($goods_spec_list as $k=>$item) {
                    if($item->id == $value['goods_specific_id']) {
                        $sum_price += $item->price*$value['count'];
                        $item->count = $value['count'];
                        if(isset($value['is_vip_product']) && $value['is_vip_product']) {
                            if($item->product->category->id != 1 ) {
                                return response()->error('PARAM_ERROR');
                            }
                            $item->is_vip_product = $value['is_vip_product'];
                            $item->is_gift = $value['is_gift'];
                            $item->phone = isset($value['phone'])?$value['phone']:'';
                        }

                        if(isset($value['cart_id']) && $value['cart_id']) {
                            CartService::DelOne($value['cart_id']);
                        }
                        break;
                    }
                }
            }
            # 生成订单号
            $rand_num = mt_rand(0,9999);
            $trade_no = date('YmdHis').str_pad($rand_num,4-strlen($rand_num),'0',STR_PAD_LEFT);
            $order_data = array(
                'trade_no'=>$trade_no,
                'uid' => $uid,
                'amount'=>$sum_price,
                'pay_time'=>date('Y-m-d H:i:s'),
                'payment_source'=>$input_arr['payment_source'],
                'create_ip'=>$request->ip(),
                'addr_id'=>$input_arr['addr_id'],
                'ship_fee'=>0, //TODO 暂时都设置为0，以后再改
                'remark'=>$input_arr['remark']
            );
            $discount = 0;
            # 优惠券逻辑
            if(isset($input_arr['discount_coupon_id']) && $input_arr['discount_coupon_id']) {
                $coupon_info = CouponService::getCouponById($input_arr['discount_coupon_id']);
                if(!$coupon_info) {
                    return response()->error('COUPON_NOT_EXIST');
                }
                if(!$coupon_info->uid != $uid) {
                    return response()->error('COUPON_OWNER_ERROR');
                }
                $discount = $coupon_info->discount;
                $order_data['discount'] = $discount;
                $order_data['discount_coupon_id'] = $coupon_info->id;
                $sum_price-=$discount;
            }
            if($input_arr['payment_source'] == 'ALIPAY') {
                $pay_result = OrderService::alipay_pay($trade_no,'0.01','商品购买',env('ALIPAY_NOTIFY'));
                \Log::info($pay_result);
            }else{
                //$pay_result =
            }
            # 统一下单
           /* $pay_data = array(
                'price'=> 1,//$sum_price * 100,
                'create_ip'=> $request->getClientIp(),
                'openid'=> $this->getLoginUserWechatOpenId(),
                'body' => '购买商品',
                'detail' => '购买商品',
                'trade_no' => $trade_no,
                'remark' => $input_arr['remark'],
                'notify_url' => env('OFFICIAL_PAY_CALL_BACK_URL'),
            );*/
            //\Log::info($pay_data);
            //$payResultInfo = OrderService::create_unpay($pay_data);
            //$payResultInfo['order'] = $trade_no;
            # 生成订单
            $order_info = OrderService::saveUnPAIDOrder($order_data);
            # 生成子订单
            $this->create_order_products($goods_spec_list,$order_info,$sum_price,$discount);
            \DB::commit();
        }catch (\Exception $e){
            \Log::error('create_order_failed:'.$e->getMessage());
            \DB::rollback();
            return response()->error('CREATE_ORDER_ERROR');
        }
        /*if(!isset($payResultInfo['appId']) || !isset($payResultInfo['package'])) {
            \Log::error('CREATE_ORDER_ERROR:'.json_encode($payResultInfo));
            return response()->error('CREATE_ORDER_ERROR');
        }*/
        //return response()->success($payResultInfo);
        return response()->success($pay_result);
    }

    /**
     * 计算订单总价
     * @param Request $request
     * @return mixed
     */
    public function CalcGoodsAmount(Request $request) {
        $uid = $this->getLoginUserId();
        $inputs = $request->json();
        $input_arr = $inputs->all();
        /*\Log::info(json_encode($input_arr));
        \Log::info(json_encode($inputs));
        \Log::info(file_get_contents('php://input'));*/
        if(!$input_arr) {
            return response()->error('PARAM_EMPTY');
        }
        if(!$this->validate_order_input_param($input_arr,0)) {
            return response()->error('PARAM_ERROR');
        }
        $sum_price = 0;
        $goods_spec_id_list = array_column($input_arr['goods_list'],'goods_specific_id');
        $goods_spec_list = ProductsSpecifictionService::getProductSpecByIds($goods_spec_id_list);

        foreach ($input_arr['goods_list'] as $key=>$value) {
            foreach ($goods_spec_list as $k=>$item) {
                if($item->id == $value['goods_specific_id']) {
                    $sum_price += $item->price*$value['count'];
                    $item->count = $value['count'];
                    break;
                }
            }
        }
        $sum_price=number_format($sum_price,2);
        //\Log::info($sum_price);
        return response()->success($sum_price);
    }

    /**
     * 验证下单接口上传的数据
     * @param $input_arr
     * @param $type 1生成订单 0计算总价
     * @return bool
     */
    private function validate_order_input_param($input_arr,$type=1) {
        if(!array_key_exists('goods_list',$input_arr)) {
            return false;
        }
        if($type == 1 && (!array_key_exists('addr_id',$input_arr) || $input_arr['addr_id'] ==0)  ) {
            return false;
        }
        foreach ($input_arr['goods_list'] as $key=>$value) {
            if(!array_key_exists('goods_id',$value) || !array_key_exists('goods_specific_id',$value) || !array_key_exists('count',$value) || $value['count']<1) {
                return false;
            }
        }
        return true;
    }

    /**
     * 生成子订单
     * @param $goods_list
     * @param $order_info
     * @param $sum_price
     * @param int $discount
     * @return mixed
     */
    private function create_order_products($goods_list,$order_info,$sum_price,$discount=0) {
        foreach ($goods_list as $key=>$item) {
            $amount = $item->price*$item->count;
            $discount_rate = round(($amount/$sum_price)*100,0);
            $rand_num = mt_rand(0,9999);
            $data_item = array(
                'order_id'=>$order_info->id,
                'ship_fee'=>0,  //暂设0
                'sub_trade_no'=>date('YmdHis').str_pad($rand_num,4-strlen($rand_num),'0',STR_PAD_LEFT),
                'uid'=>$order_info->uid,
                'product_id'=>$item->product->id,
                'product_spec_id'=>$item->id,
                'price'=>$item->price,
                'count'=>$item->count,
                'amount'=>$amount,
                'discount_rate' =>$discount_rate,
                'discount'=>round($discount_rate*$discount/100,2),
                'is_vip_product'=>isset($item->is_vip_product)?$item->is_vip_product:0,
                'is_gift'=>isset($item->is_gift)?$item->is_gift:0,
                'created_at'=>date('Y-m-d H:i:s'),
                'updated_at'=>date('Y-m-d H:i:s'),
            );
            $order_product = OrderProductsService::addOne($data_item);

            if($item->is_vip_product == 1 && $item->is_gift == 1) {
                $gift_send_data = array(
                    'uid'=>$order_info->uid,
                    'order_product_id'=>$order_product->id,
                    'send_for_phone'=>$item->phone,
                    'status'=>0
                );
                GiftSendService::addOne($gift_send_data);
            }
        }
    }

    /**
     * 订单列表
     * @param Request $request
     * @return mixed
     */
    public function order_list(Request $request) {
        $status =  $request->input('status','');
        if($status && !in_array($status,array_keys(OrderProductsService::ORDER_STATUS_STR_TO_NUM_HASH))) {
            return response()->error('PARAM_ERROR');
        }
        $uid = $this->getLoginUserId();
        $filter = compact('status');
        \Log::info($filter);
        /*if($status) {
            $filter['status'] = OrderProductsService::ORDER_STATUS_STR_TO_NUM_HASH[$status];
        }*/
        $order_list = OrderProductsService::getUserOrderAndSubUnionList($uid,$filter);
        foreach ($order_list as $order) {
            if($order->type == 1) {
                $sub_orders = OrderProductsService::getOrderProductsInfoByOrderId($order->id);
                foreach ($sub_orders as $sub_order) {
                    $sub_order->img_thum = env('APP_DOMAIN').$sub_order->img_thum;
                }
                $price_sum = $sub_orders->sum('price');
                $discount_sum = $sub_orders->sum('discount');
                $amount_sum = $sub_orders->sum('amount');
                $order->sub_orders = $sub_orders;
                $order->count = $sub_orders->sum('count');
                $order->price = $price_sum;
                $order->discount = $discount_sum;
                $order->amount = $amount_sum;
                //$order->status = OrderProductsService::ORDER_STATUS_NUM_TO_STR_HASH[$order->status];
            }else{
                $sub_orders = collect([
                    [
                        'id'=>$order->id,
                        'trade_no'=>$order->trade_no,
                        'status'=>$order->status,
                        'created_at'=>$order->created_at,
                        'count'=>$order->count,
                        'price'=>$order->price,
                        'amount'=>$order->amount,
                        'discount'=>$order->discount,
                        'img_thum'=>env('APP_DOMAIN').$order->img_thum,
                        'product_name'=>$order->product_name,
                        'specification'=>$order->specification,
                    ]
                ]);
                $order->sub_orders = $sub_orders;
            }
            $order->status = OrderProductsService::ORDER_STATUS_NUM_TO_STR_HASH[$order->status];

        }
        return response()->pagination($order_list);
    }

    public function pay(Request $request) {
        $order_id = $request->input('order_id','');
        $payment_source = $request->input('payment_source','');
        $uid = $this->getLoginUserId();
        if(empty($order_id) || !in_array($payment_source,['ALIPAY','WECHAT'])) {
            return response()->error('PARAM_EMPTY');
        }
        $order_info = OrderService::findById($order_id);
        if(empty($order_info)||$order_info->uid != $uid) {
            return response()->error('ORDER_NOT_EXISTS');
        }
        if($order_info->status !=0 ) {
            return response()->error('HAS_PAID');
        }
        # 统一下单
        /*$pay_data = array(
            'price'=> 1,//$sum_price * 100,
            'create_ip'=> $request->getClientIp(),
            'openid'=> $this->getLoginUserWechatOpenId(),
            'body' => '购买商品',
            'detail' => '购买商品',
            'trade_no' => $order_info->trade_no,
            'remark' => $order_info->remark,
            'notify_url' => env('OFFICIAL_PAY_CALL_BACK_URL'),
        );*/
        //\Log::info($pay_data);
        /*$payResultInfo = OrderService::create_unpay($pay_data);
        $payResultInfo['order'] = $order_info->trade_no;
        if(!isset($payResultInfo['appId']) || !isset($payResultInfo['package'])) {
            \Log::error('CREATE_ORDER_ERROR:'.json_encode($payResultInfo));
            return response()->error('PAID_FAILED');
        }*/
        if($payment_source == 'ALIPAY') {
            $payResultInfo = OrderService::alipay_pay($order_info->trade_no,'0.01','商品购买',env('ALIPAY_NOTIFY')); //TODO 正式上线支付金额改为实际金额
            \Log::info($payResultInfo);
        }

        return response()->success($payResultInfo);
    }

    /**
     * @param Request $request
     * @return mixed
     */
    public function confirm_obtain_goods(Request $request) {
        $order_product_id = $request->input('order_product_id','');
        $uid = $this->getLoginUserId();
        $order_product = OrderProductsService::getById($order_product_id);
        //\Log::info(json_encode($order_product));
        //\Log::info($uid);
        if($uid != $order_product->uid) {
            return response()->error('CONFIRM_GET_FAILED');
        }
        if(empty($order_product) || $order_product->status != 5) {
            return response()->error('CONFIRM_GET_FAILED');
        }
        $order_product->status = 6;
        $order_product->obtain_time = date('Y-m-d H:i:s');
        $order_product->save();
        return response()->success();
    }
}